<?php
/**
 * OrderService.php
 * description:
 * Created by www.
 * User: SCF
 * Date: 2018/11/7 17:32
 *
 */

namespace App\Services;

use App\Models\Order;
use App\Models\OrderRepairRecord;
use common\enum\CommonEnum;
use common\utils\Export;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Redis;
use common\utils\SysCode;

class OrderService
{
    // =========注单状态常量定义=========================
    const ORDER_STATUS_ALL = -1;// 全部
    const ORDER_STATUS_WAITING = 0;//等待
    const ORDER_STATUS_ACCEPT = 1;//接受
    const ORDER_STATUS_SETTLED = 2;//结算
    const ORDER_STATUS_CANCELED = 3;//取消
    const ORDER_STATUS_REFUSED = 4;//拒绝

    // 沙巴体育结算状态
    const SB_HALF_WON ="half won";//赢半
    const SB_HALF_LOSE ="half lose";//输半
    const SB_WON = "won";//全赢
    const SB_LOSE = "lose";//全输
    const SB_REFUND = "refund";//退款
    const SB_DRAW = "draw";//打和
    const SB_WAITING = "waiting";//等待
    const SB_REJECT = "reject";//拒绝
    const SB_VOID = "void";//注单作废
    const SB_RUNNING = "running";//进行中

    // UG体育
    const UG_ORDER_STATUS_WAITING = 0;//打和
    const UG_ORDER_STATUS_FULL_WIN = 1;//全赢
    const UG_ORDER_STATUS_FULL_LOST = 2;// 全输
    const UG_ORDER_STATUS_HALF_LOST = 3;// 输半
    const UG_ORDER_STATUS_HALF_WIN = 5;// 赢半

    // 电竞注单  51:无效单 52:未审核 53:未通过 54:已审核 55:系统无 效单 56: 中奖 57:无赛果 58:未中奖
    const HC_ORDER_INVALID = 51;
    const HC_ORDER_UN_CHECK = 52;
    const HC_ORDER_NO_PASS = 53;
    const HC_ORDER_CHECKED = 54;
    const HC_ORDER_SYSTEM_INVALID = 55;
    const HC_ORDER_WON = 56;
    const HC_ORDER_NO_RESULT = 57;
    const HC_ORDER_LOST = 58;

    // 定义注单查询结果 全输，全赢，输半，赢半
    const ORDER_QUERY_RESULT_FULL_ALL = 0;//全部
    const ORDER_QUERY_RESULT_FULL_WIN = 1;//全赢
    const ORDER_QUERY_RESULT_FULL_LOST = 2;// 全输
    const ORDER_QUERY_RESULT_HALF_WIN = 3;// 赢半
    const ORDER_QUERY_RESULT_HALF_LOST = 4;// 输半

    // 定义注单状态 全部，未结算，已结算，退款，拒绝，待定，取消
    const ORDER_QUERY_STATUS_ALL = 0;//全部
    const ORDER_QUERY_STATUS_SETTLED = 1;//已结算
    const ORDER_QUERY_STATUS_OPEN = 2;// 未结算
    const ORDER_QUERY_STATUS_REFUND = 3;//退款
    const ORDER_QUERY_STATUS_REJECT = 4;//拒绝
    const ORDER_QUERY_STATUS_WAITING = 5;//待定
    const ORDER_QUERY_STATUS_CANCELED = 6;//取消

    const ORDER_STATUS = [
        self::ORDER_STATUS_WAITING => "等待",
        self::ORDER_STATUS_ACCEPT => "接受",
        self::ORDER_STATUS_SETTLED => "结算",
        self::ORDER_STATUS_CANCELED => "取消",
        self::ORDER_STATUS_REFUSED => "拒绝",
    ];

    public static function getOrders($condition,$type)
    {
        $condition['hall_id'] = 0;
        if ($condition['hall_name']){
            $id = HallService::getHallIdByName ($condition['hall_name']);
            $condition['hall_id'] = current (static::formatToArray($id));
        }

        $select = [
            'or.hall_id',// 厅主id
            'hall.company_name',//厅主名称
            'or.user_id',//会员id
            'or.username',//会员账号
            'or.order_number',//注单号
            'or.bet_time',// 注单时间
            'or.partner_account',//第三方账号
            'or.game_name',//游戏名称
            'or.bet_content',//投注内容
            'or.status',//注单状态
            'or.partner_status',//API注单状态
            'or.bet_amount',// 投注金额
            'or.validbet',// 有效投注金额
            'or.profit',// 输赢
            'or.source',// 原始数据
            'or.prize',// 派奖金额
            'or.contribute_amount', //贡献
            'or.partner_name',    //第三方名称
            'or.reckon_time'    //结算时间
        ];
        $query = DB::table ('order as or')
            ->leftJoin ('hall as hall','or.hall_id', '=', 'hall.id')
            ->where(['or.game_type'=>$type]);
        if ($condition['date_type'] ==1){
            $query->whereBetween ('or.bet_time',[$condition['date_begin'],$condition['date_end']]);
        }else{
            $query->whereBetween ('or.reckon_time',[$condition['date_begin'],$condition['date_end']]);
        }
        if ($condition['hall_name']){
            $query->where(['or.hall_id'=>$condition['hall_id']]);
        }
        if ($condition['partnerID']){
            $query->where(['or.partner_id'=>$condition['partnerID']]);
        }
        if ($condition['username']){
            $query->where(['or.username'=>$condition['username']]);
        }
        if ($condition['order_number']){
            $query->where(['or.order_number'=>$condition['order_number']]);
        }

        // 状态  只有电竞， 体育有  电竞 【全输，全赢，未结算】 体育 【全输，全赢，输半，赢半，未结算】
        if ((isset($condition['status']) && $condition['status'])||(isset($condition['result']) && $condition['result'])){
            // 电竞 ： 51:无效单 52:未审核 53:未通过 54:已审核 55:系统无 效单 56: 中奖 57:无赛果 58:未中奖
            if($type==CommonEnum::GAME_ESPORT){
                // 全赢
                if ($condition['result'] == self::ORDER_QUERY_RESULT_FULL_WIN){
                    $query->where(['or.status'=>self::ORDER_STATUS_SETTLED]);
                    $query->where(['or.partner_status'=>self::HC_ORDER_WON]);
                }
                // 全输
                if ($condition['result'] == self::ORDER_QUERY_RESULT_FULL_LOST){
                    $query->where(['or.status'=>self::ORDER_STATUS_SETTLED]);
                    $query->where(['or.partner_status'=>self::HC_ORDER_LOST]);
                }
                //已结算
                if ($condition['status'] == self::ORDER_QUERY_STATUS_SETTLED){
                    $query->where(['or.status'=>self::ORDER_STATUS_SETTLED]);
                }
                //未结算
                if ($condition['status'] == self::ORDER_QUERY_STATUS_OPEN){
                    $query->where(['or.partner_status'=>self::HC_ORDER_CHECKED]);
                }
                //退款
                if ($condition['status'] == self::ORDER_QUERY_STATUS_REFUND){
                    $query->where(['or.partner_status'=>self::HC_ORDER_NO_RESULT]);
                }
                //拒绝
                if ($condition['status'] == self::ORDER_QUERY_STATUS_REJECT){
                    $query->where(['or.partner_status'=>self::HC_ORDER_NO_PASS]);
                }
                //待定
                if ($condition['status'] == self::ORDER_QUERY_STATUS_WAITING){
                    $query->where(['or.partner_status'=>self::HC_ORDER_UN_CHECK]);
                }
                //取消
                if ($condition['status'] == self::ORDER_QUERY_STATUS_CANCELED){
                    $query->whereIn('or.partner_status',[self::HC_ORDER_INVALID,self::HC_ORDER_SYSTEM_INVALID]);
                }

            }
            // 体育SB "half won" => "赢半", "half lose" => "输半","won" => "全赢","lose" => "全输","refund" => "退款",
            //"draw" => "打和","waiting" => "等待","reject" => "拒绝","void" => "注单作废","running" => "进行中",
            if($type==CommonEnum::GAME_SPORT){
                // 全赢
                if ($condition['result'] == self::ORDER_QUERY_RESULT_FULL_WIN){
                    //$query->where(['or.status'=>self::ORDER_STATUS_SETTLED]);
                    if(isset($condition['partner_name']) && $condition['partner_name']=='SB') {
                        $query->where(['or.partner_status'=> self::SB_WON]);
                    }
                    if(isset($condition['partner_name']) && ($condition['partner_name']=='UG')){
                        $query->where(['or.partner_status'=>self::UG_ORDER_STATUS_FULL_WIN]);
                    }
                    if(!isset($condition['partner_name']) || $condition['partner_name']=='ALL'){
                        $query->whereIn('or.partner_status',[self::SB_WON,self::UG_ORDER_STATUS_FULL_WIN]);
                    }
                }
                // 全输
                if ($condition['result'] == self::ORDER_QUERY_RESULT_FULL_LOST){
                    //$query->where(['or.status'=>self::ORDER_STATUS_SETTLED]);
                    if(isset($condition['partner_name']) && $condition['partner_name']=='SB') {
                        $query->where(['or.partner_status' => self::SB_LOSE]);
                    }
                    if(isset($condition['partner_name']) && ($condition['partner_name']=='UG')){
                        $query->where(['or.partner_status'=>self::UG_ORDER_STATUS_FULL_LOST]);
                    }
                    if(!isset($condition['partner_name']) || $condition['partner_name']=='ALL'){
                        $query->whereIn('or.partner_status',[self::SB_LOSE,self::UG_ORDER_STATUS_FULL_LOST]);
                    }
                }
                // 输半
                if ($condition['result'] == self::ORDER_QUERY_RESULT_FULL_LOST){
                    //$query->where(['or.status'=>self::ORDER_STATUS_SETTLED]);
                    if(isset($condition['partner_name']) && $condition['partner_name']=='SB') {
                        $query->where(['or.partner_status' => self::SB_HALF_LOSE]);
                    }
                    if(isset($condition['partner_name']) && ($condition['partner_name']=='UG')){
                        $query->where(['or.partner_status'=>self::UG_ORDER_STATUS_HALF_LOST]);
                    }
                    if(!isset($condition['partner_name']) || $condition['partner_name']=='ALL'){
                        $query->whereIn('or.partner_status',[self::SB_HALF_LOSE,self::UG_ORDER_STATUS_HALF_LOST]);
                    }
                }
                // 赢半
                if ($condition['result'] == self::ORDER_QUERY_RESULT_HALF_WIN){
                    //$query->where(['or.status'=>self::ORDER_STATUS_SETTLED]);
                    if(isset($condition['partner_name']) && $condition['partner_name']=='SB') {
                        $query->where(['or.partner_status' => self::SB_HALF_WON]);
                    }
                    if(isset($condition['partner_name']) && ($condition['partner_name']=='UG')){
                        $query->where(['or.partner_status'=>self::UG_ORDER_STATUS_HALF_WIN]);
                    }
                    if(!isset($condition['partner_name']) || $condition['partner_name']=='ALL'){
                        $query->whereIn('or.partner_status',[self::SB_HALF_WON,self::UG_ORDER_STATUS_HALF_WIN]);
                    }
                }

                //已结算
                if ($condition['status'] == self::ORDER_QUERY_STATUS_SETTLED){
                    $query->where(['or.status'=>self::ORDER_STATUS_SETTLED]);
                }
                //未结算
                if ($condition['status'] == self::ORDER_QUERY_STATUS_OPEN){
                    $query->where(['or.partner_status'=>self::SB_RUNNING]);
                }
                //退款
                if ($condition['status'] == self::ORDER_QUERY_STATUS_REFUND){
                    $query->where(['or.partner_status'=>self::SB_REFUND]);
                }
                //拒绝
                if ($condition['status'] == self::ORDER_QUERY_STATUS_REJECT){
                    $query->where(['or.partner_status'=>self::SB_REJECT]);
                }
                //待定
                if ($condition['status'] == self::ORDER_QUERY_STATUS_WAITING){
                    $query->where(['or.partner_status'=>self::SB_WAITING]);
                }
                //取消
                if ($condition['status'] == self::ORDER_QUERY_STATUS_CANCELED){
                    $query->where(['or.partner_status'=>self::SB_VOID]);
                }
            }

        }

        if ($condition['is_download']){
            $file = date ('Y-m-d',strtotime ($condition['date_begin'])).'-'.date ('Y-m-d',strtotime ($condition['date_end'])).'注单查询';
            $labels = [
                'company_name' => '厅主名称',
                'username'   => '会员账号',
                'order_number'   => '注单号',
                'bet_time'   => '投注时间',
                'partner_account'   => '第三方账号',
                'game_name'   => '游戏名称',
                'bet_content'   => '游戏内容',
                'bet_amount'   => '投注金额',
                'validbet'   => '有效投注金额',
                'profit'   => '会员输赢'
            ];
            if ($type == CommonEnum::GAME_SPORT || $type == CommonEnum::GAME_ESPORT){
                $labels2 = [
                    'status' => '状态',
                    'partner_status' =>'结算状态'
                ];
                $labels = array_merge ($labels,$labels2);
            }
            $data = static::formatToArray ($query->get ()->toArray ());
        }
        // 总计查询
        $select2  = [
            DB::raw('IFNULL(sum(or.bet_amount),0) as bet_amount'),
            DB::raw('IFNULL(sum(or.validbet),0) as validbet'),
            DB::raw('IFNULL(sum(or.profit),0) as profit'),
            DB::raw('IFNULL(sum(or.prize),0) as prize'),
            DB::raw('IFNULL(sum(or.contribute_amount),0) as contribute_amount')
        ];
        $totalResult = static::formatToArray (current ($query->select ($select2)->get ()->toArray ()));
        //DB::connection()->enableQueryLog();#开启执行日志
        $result = static::formatToArray (get_page_data($query->select ($select), $condition['page'], $condition['page_size']));
        //print_r(DB::getQueryLog());   //获取查询语句、参数和执行时间
        foreach ($result['list'] as $k=>$item){
            if ($type==CommonEnum::GAME_CARD){
                $source = json_decode ($item['source'],true);
                $result['list'][$k]['tableID'] = $source['TableID']??'';
            }
            $result['list'][$k]['bet_reckon'] = $item['bet_time']."<br/>".$item['reckon_time'];
            unset($result['list'][$k]['source']);
        }
        $list = $result['list'];
        $result['subTotalSum'] = [
            'bet_amount'=> !empty($list) ? array_sum(array_column($list, 'bet_amount')) : 0 ,
            'validbet'=> !empty($list) ? array_sum(array_column($list, 'validbet')) : 0 ,
            'profit'=> !empty($list) ? array_sum(array_column($list, 'profit')) : 0 ,
            'prize'=> !empty($list) ? array_sum(array_column($list, 'prize')) : 0,
            'contribute_amount' =>!empty($list) ? array_sum(array_column($list, 'contribute_amount')) : 0
        ];

        $result['totalSum'] = [
            'bet_amount'=> isset($totalResult['bet_amount']) ? $totalResult['bet_amount']: 0,
            'validbet'=> isset($totalResult['validbet']) ? $totalResult['validbet']:0,
            'profit'=> isset($totalResult['profit']) ? $totalResult['profit'] : 0 ,
            'prize'=> isset($totalResult['prize']) ? $totalResult['prize'] : 0,
            'contribute_amount'=> isset($totalResult['contribute_amount']) ? $totalResult['contribute_amount'] : 0

        ];
        if ($condition['is_download']){
            amount_format_array($data, ['bet_amount','validbet','profit','prize']);
            amount_format_array($result['totalSum'], ['bet_amount','validbet','profit']);
            foreach ($data as &$order){
                $order['bet_content'] = strip_tags($order['bet_content']);
                $order['status'] = self::ORDER_STATUS[$order['status']];
            }
            Export::exportExcel ($file, $labels, $data,$result['totalSum']);
        }
        return $result;
    }

    public static function formatToArray($std){
        return json_decode (json_encode ($std),true);
    }

    //补单
    public static function repairOrder($condition)
    {
        $partner = current (PartnerService::getPartnerById ($condition['partnerID']));
        $repairInfo = OrderRepairRecord::where(['status' => CommonEnum::ENABLED, 'partner_id' => $condition['partnerID']])->get()->toArray();
        if ($repairInfo){
            error_exit(SysCode::ORDER_REPAIR_ERROR);
        }
        if (strtotime ($condition['date_end']) > time ()){
            error_exit(SysCode::ORDER_REPAIR_END_TIME_ERROR,'结束时间不能大于当前时间！');
        }
        $user = Auth::user ();
        $insertValue = [
            'partner_id' => $partner['id'],
            'partner_name' => $partner['name'],
            'creator_id'   => $user->id,
            'creator_name' => $user->username,
            'begin_time'   => $condition['date_begin'],
            'end_time'     => $condition['date_end'],
            'current_time' => $condition['date_begin'],
            'status'       => CommonEnum::REPAIR_STATUS_PENDING
        ];
        $model = new OrderRepairRecord($insertValue);
        $res = $model->save();
        if (!$res) {
            Log::error("补单记录表插入失败: " . json_encode($model->getErrors(), JSON_UNESCAPED_UNICODE));
            return false;
        }
        return ['is_repair'=>CommonEnum::ENABLED??CommonEnum::DISABLE];
    }

    //获取补单记录
    public static function getRepairOrders($condition)
    {
        //DB::connection()->enableQueryLog();#开启执行日志
        $query = OrderRepairRecord::whereBetween ('created_at',[$condition['date_begin'],$condition['date_end']]);
        if ($condition['username']){
            $query->where(['creator_name'=>$condition['username']]);
        }
        if ($condition['status']){
            $query->where(['status'=>$condition['status']]);
        }
        $data = $query->orderBy('created_at','DESC')->get()->toArray();
        //print_r(DB::getQueryLog());   //获取查询语句、参数和执行时间
        return $data;
    }
}